import 'dart:async';

import 'package:convergence_media/features/api/apis/circle_csavs_api.dart';
import 'package:convergence_media/features/api/apis/navadmin_api.dart';
import 'package:convergence_media/features/api/apis/news_csavs_api.dart';
import 'package:convergence_media/features/app/repository/app_config_repository.dart';
import 'package:convergence_media/features/config/errors/login_errors.dart';
import 'package:convergence_media/features/config/logger/logger.dart';
import 'package:convergence_media/features/user/entities/nav_user_model.dart';
import 'package:convergence_media/features/user/repositories/nav_user_repository.dart';
import 'package:convergence_media/features/user/repositories/token_repository.dart';
import 'package:flutter/foundation.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'main_auth_service.g.dart';

@riverpod
MainAuthService mainAuthService(MainAuthServiceRef ref) => MainAuthService(
      navUserRepository: ref.watch(navUserRepositoryProvider),
      navadminApi: ref.watch(navadminApiProvider),
      tokenRepository: ref.watch(tokenRepositoryProvider),
      appConfigRepository: ref.watch(appConfigRepositoryProvider),
      circleCsavsApi: ref.watch(circleCsavsApiProvider),
      newsCsavsApi: ref.watch(newsCsavsApiProvider),
    );

/// {@template main_auth_repository}
/// 统一认证登录服务
/// {@endtemplate}
class MainAuthService {
  /// {@macro main_auth_repository}
  MainAuthService({
    required CircleCsavsApi circleCsavsApi,
    required NewsCsavsApi newsCsavsApi,
    required AppConfigRepository appConfigRepository,
    required NavUserRepository navUserRepository,
    required NavadminApi navadminApi,
    required TokenRepository tokenRepository,
  })  : _newsCsavsApi = newsCsavsApi,
        _circleCsavsApi = circleCsavsApi,
        _appConfigRepository = appConfigRepository,
        _navUserRepository = navUserRepository,
        _navadminApi = navadminApi,
        _tokenRepository = tokenRepository;

  final TokenRepository _tokenRepository;
  final NavadminApi _navadminApi;
  final NavUserRepository _navUserRepository;
  final AppConfigRepository _appConfigRepository;
  final CircleCsavsApi _circleCsavsApi;
  final NewsCsavsApi _newsCsavsApi;

  /// 获取验证码
  Future<void> getVerificationCode(String phone) async {
    if (phone.length != 11) {
      throw Exception('手机号长度不对');
    }
    final smsSendResponse = await _navadminApi.postSmsSend(phone);
    logger.t(smsSendResponse);
    if (smsSendResponse.code == 0) {
      throw AuthException(logMessage: smsSendResponse.msg);
    }
  }

  /// 登录
  Future<void> login(String phone, String verificationCode) async {
    // 卫语句
    if (phone.length != 11) {
      throw Exception('手机号码长度不对');
    }
    if (verificationCode.length != 4) {
      throw Exception('验证码有误');
    }

    // 发送登录
    final userMobileloginResponse =
        await _navadminApi.postUserMobilelogin(phone, verificationCode);
    logger.t('message');
    // 异常处理
    if (userMobileloginResponse.code != 1) {
      if (kDebugMode) {
        print(userMobileloginResponse);
      }
      throw AuthException.requestError(error: userMobileloginResponse.msg);
    }
    logger.t('message');

    // 获取用户信息
    final userinfo = userMobileloginResponse.data!.userinfo;
    logger.t('message');

    // 配置当前用户的手机号
    await _appConfigRepository.putPhoneNumber(phone);
    // 拿到全局唯一 id，一定存在，标记为!
    final currentHashId = _appConfigRepository.getCurrentHashId()!;
    logger.t('message');

    // 对于新登录的，需要使用手机号初始化 token 仓库
    await _tokenRepository.initTokenModel(phone);
    // 存储 token
    await _tokenRepository.putMainToken(
      currentHashId,
      userinfo.token,
    );
    logger.t('message');

    // 缓存 nav 中获取到的用户信息
    final navUserModel = NavUserModel(
      mobile: userinfo.mobile,
      username: userinfo.username,
      nickname: userinfo.nickname,
      avatar: userinfo.avatar,
      score: userinfo.score,
      token: userinfo.token,
      userId: userinfo.userId,
      createtime: userinfo.createtime,
      expiretime: userinfo.expiretime,
      expiresIn: userinfo.expiresIn,
    );
    await _navUserRepository.saveNavUser(navUserModel);

    // TODO(lilua): 圈子登录
    logger.t('圈子登录开始');
    final postLoginTokenLogin =
        await _circleCsavsApi.postLoginTokenLogin(userinfo.token);
    await _tokenRepository.putCircleToken(
      currentHashId,
      postLoginTokenLogin.data.loginToken,
    );
    logger.t('圈子登录结束');

    // TODO(lilua): 新闻登录
    // final loginMobileResponse =
    //     await _newsCsavsApi.postLoginMobile(userinfo.token);
    // await _tokenRepository.putNewsToken(
    //   currentHashId,
    //   loginMobileResponse.d!.token,
    // );

  }
}
